package app.client.file.downs;

import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import cn.lily.com.file.io.FileOutputManager;

public class FileDown {
	
	private HttpURLConnection conn;
	private HttpsURLConnection httpsConn;
	private FileOutputManager fom;
	private InputStream inStream;
	private String newPath;
	
	private String charset = "UTF-8";
	
	public void downImage(String fileUrl,String newPath) throws Exception{
		
		if(fileUrl.startsWith("https://")){
			this.downImageHttps(fileUrl, newPath);
		}else{
			this.downImageHttp(fileUrl, newPath);
		}

	}
	
	public void downRefer(String fileUrl,String newPath,String refer) throws Exception{
		
		if(fileUrl.startsWith("https://")){
			this.downReferHttps(fileUrl, newPath,refer);
		}else{
			this.downReferHttp(fileUrl, newPath,refer);
		}

	}
	
	public void downImageHttp(String fileUrl,String newPath) throws Exception{
		
		this.newPath = newPath;
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.conn = (HttpURLConnection)url.openConnection();  
        
        this.conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        
        //设置中文编码
        if(this.charset != null){
        	 this.conn.setRequestProperty("Charsert", this.charset); 
        	 this.conn.setRequestProperty("Accept-Charset", this.charset);
        	 this.conn.setRequestProperty("Content-Type", "text/html; charset="+this.charset);
        }
             
        //设置请求方式为"GET"  
        this.conn.setRequestMethod("GET");  
        
        //超时响应时间为5秒  
        this.conn.setConnectTimeout(5 * 1000);
        
        //通过输入流获取图片数据  
        this.inStream = conn.getInputStream();  
         
        this.fom = new FileOutputManager();
        this.fom.loadFile(newPath);
        this.fom.resetFile();
        
        try {
        	
            this.readInputStream(inStream,fom.getFileOutputStream()); 
            
		} catch (Exception e) {
			throw e;
		} finally {
			
			try {
				fom.free();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
	        try {
	        	inStream.close();	
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
			try {
				this.conn.disconnect();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
	}
	
	public void downReferHttp(String fileUrl,String newPath,String refer) throws Exception{
		
		this.newPath = newPath;
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.conn = (HttpURLConnection)url.openConnection();  
        
        this.conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        this.conn.setRequestProperty("Referer", refer);
        
        //设置中文编码
        if(this.charset != null){
        	 this.conn.setRequestProperty("Charsert", this.charset); 
        	 this.conn.setRequestProperty("Accept-Charset", this.charset);
        	 this.conn.setRequestProperty("Content-Type", "text/html; charset="+this.charset);
        }
             
        //设置请求方式为"GET"  
        this.conn.setRequestMethod("GET");  
        
        //超时响应时间为5秒  
        this.conn.setConnectTimeout(5 * 1000);
        
        //通过输入流获取图片数据  
        this.inStream = conn.getInputStream();  
         
        this.fom = new FileOutputManager();
        this.fom.loadFile(newPath);
        this.fom.resetFile();
        
        try {
        	
            this.readInputStream(inStream,fom.getFileOutputStream()); 
            
		} catch (Exception e) {
			throw e;
		} finally {
			
			try {
				fom.free();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
	        try {
	        	inStream.close();	
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
			try {
				this.conn.disconnect();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
	}
	
	public void downReferHttps(String fileUrl,String newPath,String refer) throws Exception{
		
		this.newPath = newPath;
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.httpsConn = (HttpsURLConnection)url.openConnection();  
        
        if(fileUrl.startsWith("https://")){
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                    }
                };
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            httpsConn.setSSLSocketFactory(sc.getSocketFactory());
            HostnameVerifier hv = new HostnameVerifier() {
                @Override
                public boolean verify(String urlHostName, SSLSession session) {
                    return true;
                }
            }; 
            httpsConn.setHostnameVerifier(hv);
        }
        
        this.httpsConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        this.httpsConn.setRequestProperty("Referer", refer);
        
        //设置中文编码
        if(this.charset != null){
        	 this.httpsConn.setRequestProperty("Charsert", this.charset); 
        	 this.httpsConn.setRequestProperty("Accept-Charset", this.charset);
        	 this.httpsConn.setRequestProperty("Content-Type", "text/html; charset="+this.charset);
        }
             
        //设置请求方式为"GET"  
        this.httpsConn.setRequestMethod("GET");  
        
        //超时响应时间为5秒  
        this.httpsConn.setConnectTimeout(5 * 1000);
        
        //通过输入流获取图片数据  
        this.inStream = httpsConn.getInputStream();  
         
        this.fom = new FileOutputManager();
        this.fom.loadFile(newPath);
        this.fom.resetFile();
        
        try {
        	
            this.readInputStream(inStream,fom.getFileOutputStream()); 
            
		} catch (Exception e) {
			throw e;
		} finally {
			
			try {
				fom.free();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
	        try {
	        	inStream.close();	
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
			try {
				this.httpsConn.disconnect();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
		
	}
	
	public void downImageHttps(String fileUrl,String newPath) throws Exception{
		
		this.newPath = newPath;
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.httpsConn = (HttpsURLConnection)url.openConnection();  
        
        if(fileUrl.startsWith("https://")){
            TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return null;
                        }
                        public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                        public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                        }
                    }
                };
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            httpsConn.setSSLSocketFactory(sc.getSocketFactory());
            HostnameVerifier hv = new HostnameVerifier() {
                @Override
                public boolean verify(String urlHostName, SSLSession session) {
                    return true;
                }
            }; 
            httpsConn.setHostnameVerifier(hv);
        }
        
        this.httpsConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        
        //设置中文编码
        if(this.charset != null){
        	 this.httpsConn.setRequestProperty("Charsert", this.charset); 
        	 this.httpsConn.setRequestProperty("Accept-Charset", this.charset);
        	 this.httpsConn.setRequestProperty("Content-Type", "text/html; charset="+this.charset);
        }
             
        //设置请求方式为"GET"  
        this.httpsConn.setRequestMethod("GET");  
        
        //超时响应时间为5秒  
        this.httpsConn.setConnectTimeout(5 * 1000);
        
        //通过输入流获取图片数据  
        this.inStream = httpsConn.getInputStream();  
         
        this.fom = new FileOutputManager();
        this.fom.loadFile(newPath);
        this.fom.resetFile();
        
        try {
        	
            this.readInputStream(inStream,fom.getFileOutputStream()); 
            
		} catch (Exception e) {
			throw e;
		} finally {
			
			try {
				fom.free();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
	        try {
	        	inStream.close();	
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
			try {
				this.httpsConn.disconnect();
			} catch (Exception e2) {
				e2.printStackTrace();
			}
			
		}
		
	}
	
	/**
	 * 地址跳转下载
	 */
	public void downLocation(String fileUrl,String newPath) throws Exception{
		
		this.newPath = newPath;
		
		System.out.println("【URL】:"+fileUrl);
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.conn = (HttpURLConnection)url.openConnection();  
        
        //设置请求方式为"GET"  
        this.conn.setRequestMethod("GET"); 
        
        this.conn.setInstanceFollowRedirects(false);
        
        this.conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                
        //超时响应时间为5秒  
        this.conn.setConnectTimeout(5 * 1000);
 
        this.conn.connect();
        
        System.out.println("【Location】"+this.conn.getHeaderField("location"));
        
        String location = new String(this.conn.getHeaderField("location").getBytes("ISO-8859-1"), this.charset);
        
        System.out.println("【NewLocation】"+location);
        
        if(location == null || "".equals(location)){
        	this.downImage(fileUrl, newPath);
        }else{     	
        	new FileDown().downImage(location, newPath);
        }
        
	}
	
	public String getLocation(String fileUrl,String newPath) throws Exception{
		

		this.newPath = newPath;
		
		System.out.println("【URL】:"+fileUrl);
		
		URL url = new URL(fileUrl);  
			
        //打开链接  
        this.conn = (HttpURLConnection)url.openConnection();  
        
        //设置请求方式为"GET"  
        this.conn.setRequestMethod("GET"); 
        
        this.conn.setInstanceFollowRedirects(false);
        
        this.conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
                
        //超时响应时间为5秒  
        this.conn.setConnectTimeout(5 * 1000);
 
        this.conn.connect();
        
        System.out.println("【Location】"+this.conn.getHeaderField("location"));
        
        String location = new String(this.conn.getHeaderField("location").getBytes("ISO-8859-1"), this.charset);
        
        System.out.println("【NewLocation】"+location);
        
        return location;
		
	}
	
	/**
	 * 强制关闭处理
	 */
	public void stop(){
		
		try {
			this.conn.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
			this.httpsConn.disconnect();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
			this.inStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		try {
			this.fom.free();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		//删除已经生成的文件
		File file = new File(this.newPath);
		if(file.exists()){
			file.delete();
		}
		
		//强制关闭
		throw new RuntimeException("强制关闭文件下载！");
		
	}
	
	public void readInputStream(InputStream inStream,OutputStream outStream) throws Exception{    
        //创建一个Buffer字符串  
        byte[] buffer = new byte[1024];  
        //每次读取的字符串长度，如果为-1，代表全部读取完毕  
        int len = 0;  
        //使用一个输入流从buffer里把数据读取出来  
        while( (len=inStream.read(buffer)) != -1 ){  
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度  
            outStream.write(buffer, 0, len);  
            outStream.flush();
        }  
 
    } 
	
	public void setCharset(String charset){
		this.charset = charset;
	}
	
	public static void main(String[] args) throws Exception {
		FileDown down = new FileDown();
		down.downReferHttp("http://www.14book.net/down.php?bid=1&name=%F7%C8%D3%B0%A1%A4%BB%F3%D1%D5-%BA%EC%D1%D5%B6%C0%D2%D4%F7%C8%CC%EC%CF%C2", "D:/aa.txt","http://www.14book.net/download/1.html");	
	}
	
}
